cmake_minimum_required(VERSION 3.12)

#--------------------------------------------------------------
# (1) 工程相关设置
#--------------------------------------------------------------

## 设置工程名及版本信息
project(cudaNoKernel VERSION 1.0)
set(HS_TOOLBOX_NAME ${PROJECT_NAME})
set(HS_TOOLBOX_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(HS_TOOLBOX_VERSION_MINOR ${PROJECT_VERSION_MINOR})

## 设置编译模式
# set(CMAKE_BUILD_TYPE Release)
set(CMAKE_BUILD_TYPE Debug)

## 设置为 C++11 标准
set(CMAKE_CXX_STANDARD 11)

## 设置build的输出文件目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release/lib)

## 打印当前系统
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
    message(STATUS "[+] Current system: ${CMAKE_SYSTEM_NAME}")
else()
    message(STATUS "[+] Current system: ${CMAKE_SYSTEM_NAME}")
endif()

# 设置安装路径为: 当前路径下的dst文件夹
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/dst)
message(STATUS "Install Prefix: ${CMAKE_INSTALL_PREFIX}")

#--------------------------------------------------------------
# (2) 导入第三方库
# 实际上是 include 第三方库对应的 cmake 文件并调用其宏函数, 宏函数
# 中定义了第三方库的源文件、库路径等设置
#--------------------------------------------------------------

## 添加cmake模块路径
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/thirdlibs)

## 导入cuda
include(cuda_config)
MAC_CUDA_CONFIG()

## 启用openmp
find_package(OpenMP REQUIRED)
if(OpenMP_FOUND)
    message(STATUS "found openmp successfully!") 
    set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${OPENMP_CXX_FLAGS})
else()
    message(FATAL_ERROR "openmp not found!")
endif()
set(OpenMP_CXX_FLAGS ${OpenMP_CXX_FLAGS})

#--------------------------------------------------------------
# (3) 导入自定义模块
# 此步骤同(2), 但是导入的是自定义的一些代码. 另外, 此步骤额外导入
# 一个"编译宏模板", 其中定义了若干个针对不同项目的编译的宏函数, 这
# 样处理是为了方便维护, 减少cmake代码冗余.
#--------------------------------------------------------------

## 导入hs
include(hs_common_config)
MAC_HS_COMMON_CONFIG()

## 导入编译宏或函数模板
include(compile_template)

#--------------------------------------------------------------
# (4) 设置公用变量
# 将一些通用的库"组合"在一起, 方便其他项目调用.
#--------------------------------------------------------------

set(PUB_PROJ_SRC_FILES "") # 源文件
set(PUB_PROJ_INC_PATH "")  # 包含路径
set(PUB_PROJ_LINK_PATH "") # 库路径
set(PUB_PROJ_LINK_LIB "")  # 库名
set(PUB_PROJ_COMP_OPT "")  # 编译选项

## 添加 openmp
list(APPEND PUB_PROJ_LINK_LIB OpenMP::OpenMP_CXX)
list(APPEND PUB_PROJ_COMP_OPT ${OpenMP_CXX_FLAGS})

## 添加 HS 公用模块
list(APPEND PUB_PROJ_INC_PATH ${HS_PUBLIC_INC_PATH})
list(APPEND PUB_PROJ_SRC_FILES ${HS_PUBLIC_SRC_FILES})

## MSVC的编译选项(避免一些报错)
if(MSVC)
    # 解决 VS 编译中文报错 error C2001:常量中有换行符
    list(APPEND PUB_PROJ_COMP_OPT "/utf-8")
    # 解决 error C2872: “byte”: 不明确的符号
    list(APPEND PUB_PROJ_COMP_OPT "/D_HAS_STD_BYTE=0")
    # 关闭 sscanf 警告
    list(APPEND PUB_PROJ_COMP_OPT "-D_CRT_SECURE_NO_WARNINGS")
    # 避免内存不够
    list(APPEND PUB_PROJ_COMP_OPT "/bigobj")
endif()

# 定义 HS_USE_CXX_STANDARD_11 宏以启用自定义C11扩展
list(APPEND PUB_PROJ_COMP_OPT "-DHS_USE_CXX_STANDARD_11")

#--------------------------------------------------------------
# (5) 添加子项目
#--------------------------------------------------------------
add_subdirectory(cudalib)
add_subdirectory(test)
